﻿//
// GNS_SendMsgWnd.cpp
// GameHall
//
// Created by mr.l on 16/2/2.
//
//

#include "GNS_YJFLayer.h"
#include <CCUserDefault.h>
#include "GNS_IOSHelper.h"

using namespace std;
#define winsize Director::getInstance()->getVisibleSize()

enum{
	BTN_QUEDING, //确定按钮
	BTN_QUXIAO,	 //取消按钮
};

enum TextField_ENUM
{
	CANNOT_INPUT_CHINESE = 1,	 //不如许输入中文
};

GNS_YJFLayer::GNS_YJFLayer()
{
	m_RootNode = 0;
}

GNS_YJFLayer::~GNS_YJFLayer()
{

}

GNS_YJFLayer* GNS_YJFLayer::createLayer(std::string CsbName)
{
	auto pLayer = GNS_YJFLayer::create();
	auto pScene = Director::getInstance()->getRunningScene();
	if (!pScene)
		return 0;
	pScene->addChild(pLayer,10000);
	pLayer->m_RootNode=pLayer->Loadcsb(CsbName);
	pLayer->addChild(pLayer->m_RootNode);
	
	return pLayer;
}

Node* GNS_YJFLayer::Loadcsb(std::string csbName)
{
	auto node = CSLoader::createNode(csbName);
	node->setContentSize(winsize);
	node->ignoreAnchorPointForPosition(false);
	node->setAnchorPoint(Vec2(0.5,0.5));
	ui::Helper::doLayout(node);
	return node;
}

bool GNS_YJFLayer::init()
{
	if (!Layer::init())
	{
		return false;
	}
	initCursor(255, 2, 30);
	auto callback = [](Touch *, Event *)
	{
		return true;
	};	
	listener = EventListenerTouchOneByOne::create();
	listener->onTouchBegan = callback;	
	listener->setSwallowTouches(true);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

	auto kblsnr = EventListenerKeyboard::create();
	kblsnr->onKeyReleased = CC_CALLBACK_2(GNS_YJFLayer::onKeyReleased, this);
	if (m_isAddKeyboard)
	{
		_eventDispatcher->addEventListenerWithSceneGraphPriority(kblsnr, this);
	}
 	
	return true;
}


bool GNS_YJFLayer::onTouchBegan(Touch *touch, Event *unused_event)
{
	return true;
}

void GNS_YJFLayer::onTouchMoved(Touch *touch, Event *unused_event)
{

}

void GNS_YJFLayer::onTouchEnded(Touch *touch, Event *unused_event)
{

}

void GNS_YJFLayer::Show( bool isShow)
{
	auto pScene = Director::getInstance()->getRunningScene();
	if (!pScene)
		return;
	if (isShow)
	{
		listener->setSwallowTouches(true);
		m_RootNode->stopAllActions();
		m_RootNode->setPosition(Vec2(winsize.width / 2, winsize.height*1.2));
		auto NodeMove = MoveTo::create(0.5f, Vec2(winsize.width / 2, winsize.height / 2));
		auto  easeBounceOut = EaseBounceOut::create(NodeMove);
		m_RootNode->runAction(easeBounceOut);
		setVisible(isShow);
	}
	else
	{
		auto NodeMove = MoveTo::create(0.5f, Vec2(winsize.width / 2, winsize.height*1.5));
		listener->setSwallowTouches(false);
		m_RootNode->runAction(NodeMove);
		setVisible(isShow);
	}
}

char* GNS_YJFLayer::MD5Str(char* szString)
{
	return SystemMgr::getInstance()->md5String(szString);
}

string GNS_YJFLayer::GTOU(const char *inbuf)
{
	return SystemMgr::getInstance()->GbToUTF8(inbuf);
}

string GNS_YJFLayer::UTOG(const char *inbuf)
{
	return SystemMgr::getInstance()->utf8ToGb(inbuf);
}

void GNS_YJFLayer::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) 
{
	switch (keyCode)     
	{         //监听返回键        
	case EventKeyboard::KeyCode::KEY_ESCAPE:  
		ShowAndroidTips();
		break;         //监听menu键        
	case EventKeyboard::KeyCode::KEY_MENU:             
		break;     
	} 
}

void GNS_YJFLayer::BtnCallBack(Ref *pSender, ui::Widget::TouchEventType type)
{
	if (type == ui::Widget::TouchEventType::ENDED) {
		auto pButton = (Button*)pSender;
		int BtnTag = pButton->getTag();
		switch (BtnTag) {
		case 1:
		{
			Show(false);
			break;
		}
		case 2:
		{

		}
		default:
			break;
		}
	}
}

void GNS_YJFLayer::TextFileCallBack(Ref *pSender, ui::TextField::EventType type)
{
	auto textField = static_cast<TextField*>(pSender);
	auto textStr = textField->getString();
	switch (type) 
	{
		case TextField::EventType::ATTACH_WITH_IME:		//获取了焦点
		{
			break;
		}
		case TextField::EventType::DETACH_WITH_IME:		//移除了焦点
		{
			log("移除了焦点");
			if (textStr.length()>textField->getMaxLength())
			{
				textStr = textStr.substr(0, textField->getMaxLength());
			}
			break;
		}
		case TextField::EventType::DELETE_BACKWARD:		 //删除了文字
		{
			break;
		}
		case TextField::EventType::INSERT_TEXT:			//输入了文字
		{
			break;
		}
		default:
			break;
	}
}

//截取部分char，因為不全顯示
char* GNS_YJFLayer::SetShowText(char tmp_bufInfo[], char tmp_ellipsis[], int nCount)
{
	char* bufInfo = new char[80];
	memset(bufInfo, 0, sizeof(char)* 80);
	int bufIndex = 0;
	while (tmp_bufInfo[bufIndex])
	{
		//这里只需要判断第一个字节大于0x80就行了，前提是输入的是合法的GBK字符串
		//原因在于，如果第一个字节大于0x80，那么它必然和后面一个字节一起组成一个汉字
		//所以就没有必要再去判断后面一个字节了
		//再强调一下，前提条件是输入合法的GBK字符串
		if (tmp_bufInfo[bufIndex] & 0x80)
		{
			memcpy(&bufInfo[bufIndex], &tmp_bufInfo[bufIndex], sizeof(char)* 2);
			// 汉字，计数器++
			bufIndex += 2;//是汉字自然就该直接+2了
		}
		else
		{
			memcpy(&bufInfo[bufIndex], &tmp_bufInfo[bufIndex], sizeof(char));
			bufIndex++;
		}

		if (bufIndex >= nCount)
		{
			memcpy(&bufInfo[bufIndex], tmp_ellipsis, sizeof(tmp_ellipsis));
			break;
		}
	}
	return bufInfo;
}

// 连接结果
int GNS_YJFLayer::connectResult(int iClientId, int iSubCode, int iReconnectCount)
{
	switch (iSubCode)
	{
		case CC_START_NO_CIRCLE:				// 在 开始转圈的连接次数 以内，不转圈
		{
			log("CLIENT_INNER_CONNECT,  CC_START_NO_CIRCLE  %d", iReconnectCount);
			ShowConnectTips("正在请求网络数据......", true);
			break;
		}
		case CC_CONNECT_CIRCLE_ING:		// 在  >开始转圈的连接次数 并且  <=结束转圈的连接次数 范围，开始转圈【正在连接】
		{
			log("CLIENT_INNER_CONNECT,  CC_CONNECT_CIRCLE_ING  %d", iReconnectCount);
			break;
		}
		case CC_SUCC_NO_CIRCLE:				// 连接成功，结束转圈
		{
			log("CLIENT_INNER_CONNECT,  CC_SUCC_NO_CIRCLE  %d", iReconnectCount);
			//ShowConnectTips("连接成功!",false);
			break;
		}
		case CC_FAIL_NO_CIRCLE:					// 结束转圈，并弹出【连接失败】的提示框
		{
			log("CLIENT_INNER_CONNECT,  CC_FAIL_NO_CIRCLE  %d", iReconnectCount);
			ShowConnectTips("", false);
			//ShowAndroidTips("", true);
			ShowExitGameTips();
			break;
		}
	}

	return 0;
}

// 断线重连
int GNS_YJFLayer::reConnectResult(int iClientId, int iSubCode, int iReconnectCount)
{
	switch (iSubCode)
	{
		case RECC_START_NO_CIRCLE:				// 在 开始转圈的连接次数 以内，不转圈
		{
			log("CLIENT_INNER_RE_CONNECT,  RECC_START_NO_CIRCLE  %d", iReconnectCount);
			break;
		}
		case RECC_CONNECT_CIRCLE_ING:	// 在  >开始转圈的连接次数 并且  <=结束转圈的连接次数 范围，开始转圈【正在连接】
		{
			log("CLIENT_INNER_RE_CONNECT, RECC_CONNECT_CIRCLE_ING  %d", iReconnectCount);
			ShowConnectTips("正在请求网络数据......");
			break;
		}
		case RECC_SUCC_NO_CIRCLE:			// 连接成功，结束转圈
		{
			log("CLIENT_INNER_RE_CONNECT,  RECC_SUCC_NO_CIRCLE  %d", iReconnectCount);
			ShowConnectTips("连接成功!",false);
			break;
		}
		case RECC_FAIL_NO_CIRCLE:				// 结束转圈，并弹出【连接失败】的提示框
		{
			log("CLIENT_INNER_RE_CONNECT,  RECC_FAIL_NO_CIRCLE  %d", iReconnectCount);
			ShowConnectTips("", false);
			//ShowAndroidTips("", true);
			ShowExitGameTips();
			break;
		}
	}

	return 0;
}

void GNS_YJFLayer::ShowAndroidTips(string str, bool isExitGame)
{
	if (!m_AndroidTips)
	{
		m_AndroidTips = GNS_AndroidTips::createLayer("MainScenes/androidTips.csb");
		log("back__________________________");
	}
	m_AndroidTips->Show();
}


void GNS_YJFLayer::ShowExitGameTips(string str /*= ""*/)
{
	if (!m_exitGameTips)
	{
		m_exitGameTips = GNS_ExitGameTips::createLayer("MainScenes/ExitGameTips.csb");
	}
	m_exitGameTips->Show();
}

void GNS_YJFLayer::ShowCommonTips(std::string tips, bool isShow)
{
	if (!m_TipsLayer)
	{
		m_TipsLayer = GNS_TipsWnd::createLayer("MainScenes/TipsLayer.csb");
	}
	if (m_TipsLayer)
	{
		m_TipsLayer->ShowTips(tips, isShow);
	}
	
}

void GNS_YJFLayer::ShowConnectTips(string Tips,bool isShow)
{
	if (isShow)
	{
		if (!m_ConnectTipsLayer)
		{
			m_ConnectTipsLayer = GNS_TipsWnd::createLayer("MainScenes/TipsLayer.csb");
		}
	}
	if (m_ConnectTipsLayer)
	{
		m_ConnectTipsLayer->ShowConnectTips(Tips, isShow);
	}	
}

//设置文件加解密的密钥
void GNS_YJFLayer::setFileKey(int key)
{
	m_FileKey = key;
}

string GNS_YJFLayer::redaFile(string key)
{
	auto str = cocos2d::UserDefault::getInstance()->getStringForKey(key.c_str());
	string str1;
	//这里写解密
	for (int i = 0; i < str.length(); i++)
	{
		char c = (char)(str.at(i) ^ m_FileKey);
		string a = StringUtils::toString(c);
		str1.append(a);
	}

	return str1;
}

void GNS_YJFLayer::writeFile(string key, string str)
{
	//这里写加密
	string str2;
	//加密过程
	for (int i = 0; i < str.length(); i++)
	{
		char c = (char)(str.at(i)^m_FileKey);
		string a = StringUtils::toString(c);
		str2.append(a);
	}
	UserDefault::getInstance()->setStringForKey(key.c_str(), str2);
}

string GNS_YJFLayer::getUserName()
{
	return redaFile("name");
}

string GNS_YJFLayer::getinUserPass()
{
	return redaFile("pass");
}

void GNS_YJFLayer::setUserName(string str)
{
	writeFile("name", str);
}

void GNS_YJFLayer::setUserPass(string str)
{
	writeFile("pass", str);
}

void GNS_YJFLayer::getDeviceInfo(string &info, int iLen)
{
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
	// -----------------------------------------------------------------------
	// Win32上单独用硬盘序列号做唯一标识符，有可能会重复（无盘网吧 或 js刷固件？）
	// 所以Win32加上了CPU核心+网卡信息，最终标识符格式如下：
	// info=D|C|M
	// D=第一块磁盘物理序列号
	// C=CPU名称|相关性|物理处理器数量+逻辑处理器数量+处理器核心数量
	// M=第一块网卡名称,Mac地址
	// -----------------------------------------------------------------------
	// Android设备上也是一样，单独用IMEI设备序列号也可能会重复
	// 所以Android加上了
	// -----------------------------------------------------------------------
	// Cool.Cat@2014-04-04
// 	char SerialNumber[32] = { 0 };
// 	memset(&SerialNumber, 0, sizeof(SerialNumber));
// 	//SIX_SystemInfo pSysInfo;
// 	if (pSysInfo.getHDInfo(SerialNumber))
// 	{
// 		memcpy(info, SerialNumber, strlen(SerialNumber));
// 	}
// 	char CPUName[1024] = { 0 };
// 	char Hypotaxis[1024] = { 0 };
// 	int PhysicalCount = 0;
// 	int CoreCount = 0;
// 	int LogicalCount = 0;
// 	int HT = 0;
// 	long Frequency = 0;
// 	if (pSysInfo.getCPUInfo(CPUName, Hypotaxis, &PhysicalCount, &CoreCount, &LogicalCount, &HT, &Frequency))
// 	{
// 		sprintf_s(info, iLen,/*%s|%s|%s|%02d%02d%02d*/XorStr<0x03, 22, 0xFC9B8B00>("\x26\x77\x79\x23\x74\x74\x2C\x79\x77\x29\x3D\x3C\x6B\x35\x21\x20\x77\x31\x25\x24\x73" + 0xFC9B8B00).s,
// 			info, CPUName, Hypotaxis, PhysicalCount, LogicalCount, CoreCount);
// 	}
// 	MP *mp = new MP();
// 	if (pSysInfo.getAdapter(mp))
// 	{
// 		if (mp->size() > 0)
// 		{
// 			//for (int i=0;i<mp->size();i++)
// 			//	SIXLog("getAdapter[%d][%s]",i,mp->at(i).c_str());
// 			sprintf_s(info, iLen,/*%s|%s*/XorStr<0x6F, 6, 0xC1E0F450>("\x4A\x03\x0D\x57\x00" + 0xC1E0F450).s, info, mp->at(0).c_str());
// 		}
// 	}
// 	mp->clear();
//#ifdef WIN32
	//mp->swap(MP());
//#endif
	//CC_SAFE_DELETE(mp);
	info = "123";
#elif (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
	auto pModel = StringUtils::format("%s", SystemMgr::getInstance()->getDeviceModelJNI());
	auto pSerial = StringUtils::format("%s", SystemMgr::getInstance()->getSerialJNI());
	auto pMac = StringUtils::format("%s", SystemMgr::getInstance()->getMacAddressJNI());
	auto pIMSI = StringUtils::format("%s", SystemMgr::getInstance()->getIMSIJNI());
	auto pIMEI = StringUtils::format("%s", SystemMgr::getInstance()->getIMEIJNI());
	auto androidInfo = StringUtils::format("%s|%s|%s|%s|%s", pModel.c_str(), pSerial.c_str(), pMac.c_str(), pIMEI.c_str(), pIMSI.c_str());
	info = androidInfo.c_str();
#elif (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
	// 先尝试读本地缓存
//	string uuid;
//	bool retv = SIX_GlobalMgr::GetInstance()->getProData("UUID", "Identifier", uuid);
//	// e.g:3D8EED52-556B-4F71-95F0-6B50B104B866
//	//     3D8EED52556B
//	if (retv && (uuid.length() == 36 || uuid.length() == 12))
//	{
//		memcpy(info, uuid.c_str(), uuid.length());
//	}
//	else
//	{
		// 否则尝试取MAC地址
		//string pMacAddr = StringUtils::format("%s", GNS_IOSHelper::GetInstance()->getMacAddress());
//		if (!pMacAddr.compareIgnoreCase(/*020000000000*/XorStr<0x65, 13, 0xA782027F>(&"\x55\x54\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x40" [ 0xA782027F]).s))
//		{
//			// 如果是ios7以上，则用IDFA代替
//			// 新版iOS审核更严格，不能在无广告功能的前提下使用IDFA
//			// 所以这里用UUID替代
//			// Cool.Cat
//			log("Traget iOS version more then 7.Try got mac address is unsupported!");
//			pMacAddr = StringUtils::format("%s", GNS_IOSHelper::GetInstance()->getIDFA());
//		}
//		if (pMacAddr && (pMacAddr->length() == 36 || pMacAddr->length() == 12))
//		{
//			memcpy(info, pMacAddr->getCString(), pMacAddr->length());
//			// 写本地缓存
//			// Cool.Cat
//			SIX_GlobalMgr::GetInstance()->setProData("UUID", "Identifier", info);
//		}
//	}
    auto idfa = StringUtils::format("%s", GNS_IOSHelper::GetInstance()->getIDFA());
    //if ((idfa.length()==36) || (idfa.length() == 12)) {
        info = idfa;
    //}
#endif
}


void GNS_YJFLayer::initCursor(long long color, int width, int height)
{
	Color4B ccColor = ccc4((color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);

	// 24位RGB改为32位RGBA，现在支持指定光标的alpha通道了~
	// Cool.Cat
	char *pixels = new char[width*height * 4];
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			pixels[i * 4 + j * 4 + 3] = ccColor.a;
			pixels[i * 4 + j * 4 + 2] = ccColor.b;
			pixels[i * 4 + j * 4 + 1] = ccColor.g;
			pixels[i * 4 + j * 4] = ccColor.r;
		}
	}
	Texture2D *texture = new CCTexture2D();
	texture->initWithData(pixels, 25, Texture2D::PixelFormat::RGB888, 3, 25, Size(width, height));
	m_Cursor = Sprite::createWithTexture(texture);
	m_Cursor->setAnchorPoint(ccp(0, 0));
	m_Cursor->setVisible(false);
	auto CursorAction = RepeatForever::create((ActionInterval *)Sequence::create(FadeOut::create(0.5f), FadeIn::create(0.5f), 0));
	m_Cursor->runAction(CursorAction);
	// 像素内存要释放掉，这里以前没释放，导致memleak!
	// Cool.Cat
	CC_SAFE_DELETE_ARRAY(pixels);
	CC_SAFE_RELEASE(texture);
}